#region Copyright (c) 2006 Jonathan Nauman
/*       _\|/_
         (o o)
+-----oOO-{_}-OOo-----------------------+
| Copyright (c) Jonathan Naumann        |
+---------------------------------------+
| 
| File: MonoPad.XmlProvider.cs
| Version:	0.0.7
|
+
*/
#endregion

using System;
using System.Text;
using System.IO;
using System.Xml;

namespace MonoPad {
	///
	/// ErrorType as enum
	///
	public enum OpenMode {
		/// <summary> Open xml file for reading (XmlReader) </summary>
		ForReading = 0,
		/// <summary> Open xml file for writing (XmlWriter) </summary>
		ForWriting = 1,
		/// <summary> Create a xml file (XmlWriter) </summary>
		ForCreating = 2,
		/// <summary> Open a xml document with DOM (XmlWriter) </summary>
		AsDOM = 2
	};

	///
	/// Class XmlProvider
	///
	public class XmlProvider {
		private OpenMode m_OM = new OpenMode();
		private string m_strXmlFile;
		//private XmlReaderSettings xmlRS = null;
		//private XmlWriterSettings xmlWS = null;
		private XmlReader xmlR = null;
		private XmlWriter xmlW = null;
		private XmlTextReader reader = null;
		private XmlTextWriter writer = null;

		///
		/// Default constructor
		///
		public XmlProvider() : this("../TempXmlFile.xml", OpenMode.ForCreating) { }

		///
		/// Specific constructor
		/// For example: ../Configuration/Configuration.xml
		///
		public XmlProvider(string File) : this(File, OpenMode.ForReading) { }

		///
		/// Specific constructor
		///
		public XmlProvider(string File, OpenMode op) {
			m_OM = op;
			m_strXmlFile = File;
			
			if(m_OM == OpenMode.ForWriting)
				this._OpenFile();
		}
		
		///
		/// Default destructor
		///
		~XmlProvider(){
			if(m_OM == OpenMode.ForWriting)
				this._CloseFile();
		}

		///
		/// Set the file
		///
		public string File {
			set { m_strXmlFile = value; }
		}

		///
		/// Set the open mode
		///
		public OpenMode FileOpenMode {
			set { m_OM = value; }
		}

		///
		/// [PRIVATE] Close file
		///
		private void _CloseFile() {
			switch(this.m_OM) {
				case OpenMode.ForReading:
					this.reader.Close();
					break;
				
				case OpenMode.ForWriting:
					this.writer.Close();
					break;
				
				default:
					this.reader.Close();
					break;
			}
		}
		
		///
		/// Close the writer
		///
		public void ExplicitCloseWriter() {
			this.writer.Close();
		}
		
		///
		/// Close the reader
		///
		public void ExplicitCloseReader() {
			this.reader.Close();
		}

		///
		/// [PRIVATE] Open the file
		///
		private void _OpenFile() {
			switch(this.m_OM) {
				case OpenMode.ForReading:
					//xmlRS = new XmlReaderSettings();
					//xmlRS.ConformanceLevel = ConformanceLevel.Fragment;
					//xmlRS.IgnoreWhitespace = true;
					//xmlRS.IgnoreComments = true;
					
					this.reader = new XmlTextReader(m_strXmlFile);
					this.reader.MoveToContent();
					
					//xmlR = XmlReader.Create(m_strXmlFile);//, xmlRS);
					//xmlR = XmlReader.Create(new FileStream(m_strXmlFile, FileMode.Open), xmlRS);
					break;
				
				case OpenMode.ForWriting:
					//xmlWS = new XmlWriterSettings();
					//xmlWS.ConformanceLevel = ConformanceLevel.Fragment;
					
					//this.writer = new XmlTextWriter(m_strXmlFile, System.Text.Encoding.UTF8);
					try {
						this.writer = new XmlTextWriter(m_strXmlFile, null);
						this.writer.Formatting = Formatting.Indented;
						this.writer.WriteProcessingInstruction("xml", "version=\"1.0\" encoding=\"utf-8\"");
					}
					catch(Exception ex) {
						throw ex;
					}
					
					//xmlW = XmlWriter.Create(m_strXmlFile, xmlWS);
					//xmlW = XmlWriter.Create(new FileStream(m_strXmlFile, FileMode.Create), xmlWS);
					break;
				/*
				case OpenMode.ForCreating:
					xmlWS = new XmlWriterSettings();
					xmlWS.ConformanceLevel = ConformanceLevel.Fragment;

					xmlW = XmlWriter.Create(m_strXmlFile, xmlWS);
					//xmlW = XmlWriter.Create(new FileStream(m_strXmlFile, FileMode.CreateNew), xmlWS);
					break;*/

				default:
					/*xmlRS = new XmlReaderSettings();
					xmlRS.ConformanceLevel = ConformanceLevel.Fragment;
					xmlRS.IgnoreWhitespace = true;
					xmlRS.IgnoreComments = true;*/
					
					this.reader = new XmlTextReader(m_strXmlFile);
					this.reader.MoveToContent();

					//xmlR = XmlReader.Create(m_strXmlFile);//, xmlRS);
					//xmlR = XmlReader.Create(new FileStream(m_strXmlFile, FileMode.Open), xmlRS);
					break;
			}
		}
		
		///
		/// Read as long as you need to find a node
		///
		private bool ReadToFollowing(string name) {
			while(this.reader.Read()) {
				//Console.WriteLine(name + " -> " + reader.ReadString());
				if(name == this.reader.Name)
					return true;
			}
			return false;
		}
		
		///
		/// Read a specific XML tag
		///
		public string ReadTag(string Node) {
			string strTemp = "";
			
			this._OpenFile();
			
			//xmlR.
			this.ReadToFollowing(Node);
			strTemp = this.reader.ReadString();
			
			this._CloseFile();

			return strTemp;
		}
		
		///
		/// Write a specific XML root tag
		///
		public void WriteRootStartTag(string Node) {
			this.writer.WriteStartElement(Node);
		}
		
		///
		/// Write a specific XML root end tag
		///
		public void WriteRootEndTag() {
			this.writer.WriteEndElement();
		}
		
		///
		/// Write a specific XML tag
		///
		public void WriteTag(string Node, string Value) {
			this.writer.WriteElementString(Node, Value);
		}
	}
}
